home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / maestro / source / portmngr / portmngr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-15  |  9.6 KB  |  210 lines

  1. /*
  2.  * Copyright (c) 1990, 1991 Stanford University
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software and 
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name
  8.  * Stanford may not be used in any advertising or publicity relating to
  9.  * the software without the specific, prior written permission of
  10.  * Stanford.
  11.  * 
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  13.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  14.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  15.  *
  16.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  17.  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
  18.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
  19.  * ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
  20.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21.  * SOFTWARE.
  22.  */
  23.  
  24. /* $Header: /Source/Media/drapeau/PortManager/RCS/PortManager.c,v 1.7 92/09/13 22:47:00 drapeau Exp $ */
  25. /* $Log:    PortManager.c,v $
  26.  * Revision 1.7  92/09/13  22:47:00  drapeau
  27.  * Minor modification in main().  A diagnostic message used a non-portable
  28.  * method of reporting the port number on which the PortManager is listening
  29.  * for messages.  A more portable method is now used.
  30.  * 
  31.  * Revision 1.6  91/09/27  13:35:51  drapeau
  32.  * Added Revision RCS id, so that the application can be aware of the current
  33.  * revision number.
  34.  * 
  35.  * Revision 1.5  91/09/18  13:09:35  drapeau
  36.  * Minor cosmetic changes, and simple changes to better conform to ANSI-C specifications.
  37.  * Also, added entries in the DispatchTable to reflect new protocol messages, and filled in the
  38.  * GetPortFromName() slot, since the Port Manager now responds to the GetPortFromName() message.
  39.  * 
  40.  * Revision 1.4  91/09/09  18:28:19  drapeau
  41.  * Changed all diagnostic messages to go through the PrintDiagnostic() routine.
  42.  * Also, added support for obtaining command-line options, through the
  43.  * GetCommandLineOptions() routine.
  44.  * 
  45.  * Revision 1.3  91/07/31  11:11:29  drapeau
  46.  * The main() function was changed it two ways:
  47.  * 1) PortManager now checks to see if it was able to reserve the port it needs
  48.  *    to listen for messages.  If the port was not reservable, the 
  49.  *    NewReceiver() call returns a NULL Receiver*, and the Port Manager reports
  50.  *    the error and exits cleanly, without crashing.
  51.  * 2) The Port Manager makes a call to gethostname() to determine the actual
  52.  *    name of the computer on which it is listening for messages.  This is done
  53.  *    for the PortMgrConnectWithPortMgr() and PortMgrDisconnectFromPortMgr()
  54.  *    functions, so they can determine the actual hostname of a calling
  55.  *    application when the calling application says it's calling from
  56.  *    "localhost".
  57.  * 
  58.  * Revision 1.2  91/06/17  18:14:37  drapeau
  59.  * Added copyright notice.
  60.  * 
  61.  * Revision 1.1  90/11/30  13:45:42  drapeau
  62.  * Initial revision
  63.  *  */
  64.  
  65. static char portMgrRcsid[] ="$Header: /Source/Media/drapeau/PortManager/RCS/PortManager.c,v 1.7 92/09/13 22:47:00 drapeau Exp $";
  66.  
  67. static char portMgrVersionID[] = "$Revision: 1.7 $";
  68.  
  69. #include <Receiver.h>
  70. #include <Sender.h>
  71. #include "PortList.h"
  72. #include <stdio.h>
  73. #include <string.h>
  74.  
  75. void        PortMgrConnectWithPortMgr(Port* newApp);
  76. PortArray*    PortMgrGetOpenApps(void* unusedArg);
  77. void        PortMgrDisconnectFromPortMgr(Port* appToRemove);
  78. PortArray*    PortMgrGetPortFromName(Port* appPort);
  79.  
  80. char        portMgrHostName[256];
  81. Receiver*    portMgrReceiver;
  82. PortList*    portMgrPortList;
  83. DispatchTable    portMgrDispatchTable =
  84. {
  85.   NULL,                                    /* OpenDocument */
  86.   NULL,                                    /* GetCurrentDocName */
  87.   NULL,                                    /* GetSelection */
  88.   NULL,                                    /* SetSelection */
  89.   NULL,                                    /* PerformSelection */
  90.   PortMgrConnectWithPortMgr,                        /* ConnectWithPortMgr */
  91.   PortMgrGetOpenApps,                            /* GetOpenApps */
  92.   PortMgrGetPortFromName,                        /* GetPortFromName */
  93.   NULL,                                    /* DispatchMessage */
  94.   PortMgrDisconnectFromPortMgr,                        /* DisconnectFromPortMgr */
  95.   NULL,                                    /* Ping */
  96.   NULL,                                    /* HaltSelection */
  97.   NULL,                                    /* PauseSelection */
  98.   NULL,                                    /* ResumeSelection */
  99.   NULL,                                    /* HideApplication */
  100.   NULL,                                    /* ShowApplication */
  101.   NULL,                                    /* GetAppIcon */
  102.   };
  103.  
  104. extern char    diagMessage[];
  105. extern void    PrintDiagnostic(char*);
  106.  
  107. /*******************************************************************
  108.  *    This function is responsible for listening for RPC requests and dispatching them.  It also periodically
  109.  *    checks the list of apps that have registered with the Port Manager to see that they're still running.
  110.  *    If an application on the Port Manager's list is no longer running, this function removes that
  111.  *    application from the list.
  112.  */
  113.  
  114. void ListenForMessages()                        
  115. {
  116.   fd_set        rpcSockets;                    /* Variable holding list of RPC sockets to listen... */
  117.                                     /* ...on.  Used as an argument to select() to determine... */
  118.                                     /* ...whether there are requests on any RPC socket ... */
  119.                                     /* ...waiting to be processed. */
  120.   int            descriptorTableSize = 0;
  121.   int            numSockets = 0;                    /* Return value from select, tells how many files had... */
  122.                                     /* ...input ready to be processed. */
  123.   struct timeval    waitTime;                    /* Used to tell select() how long to wait until it returns */
  124.   struct timeval    lastTestTime;                    /* Holds last time the Port Manager scanned its list of... */
  125.                                     /* ...applications to see if any were invalid ("dead") */
  126.   struct timeval    now;                        /* Holds the current time */
  127.   int            updateInterval = 30;                /* Determines how often to check for "dead" apps */
  128.   int            result;                        /* Holds result of "gettimeofday()" to check for errors */
  129.   void            ScanPortListForDeadApps(PortList**);
  130.   
  131.   descriptorTableSize = getdtablesize();                /* Get size of descriptor table for later use by select() */
  132.   waitTime.tv_sec = 1;                            /* Set up a timeval to wait for 1.0 seconds */
  133.   waitTime.tv_usec = 0;
  134.   result = gettimeofday(&now,(struct timezone*)NULL);            /* Get current time */
  135.   if (result)                                /* Was there a problem getting the time of day? */
  136.     {                                    /* Yes, print an error and exit the program */
  137.     sprintf(diagMessage, "Could not get the time of day.  Exiting.\n");
  138.     PrintDiagnostic(diagMessage);
  139.     exit(result);
  140.     }
  141.   lastTestTime.tv_sec = now.tv_sec;                    /* Initialize the last time scanned to now */
  142.   lastTestTime.tv_usec = now.tv_usec;
  143.   for (;;)                                /* Loop forever */
  144.     {
  145.     rpcSockets = svc_fdset;                        /* Get the list of RPC sockets accepting requests */
  146.     numSockets = select(descriptorTableSize,                /* Check for input on RPC sockets */
  147.             &rpcSockets, (int*)0,(int*)0,            /* Only concerned with incoming stuff */
  148.             &waitTime);                    /* Tell select how long to wait (not at all, in this case) */
  149.     switch (numSockets)                            /* Based on how many sockets had input, determine what to do */
  150.       {
  151.       case -1:                                /* An error occurred */
  152.         break;                                /* For now, don't do anything */
  153.  
  154.       case 0:                                /* There was no input to process */
  155.     result = gettimeofday(&now,(struct timezone*)NULL);        /* Get current time */
  156.     if (result)                            /* Was there a problem getting the time of day? */
  157.       {                                /* Yes, print an error and exit the program */
  158.       sprintf(diagMessage, "Could not get the time of day.  Exiting.\n");
  159.       PrintDiagnostic(diagMessage);
  160.       exit(result);
  161.       }
  162.     if ((now.tv_sec - lastTestTime.tv_sec) >= updateInterval)   /* Did "updateInterval" seconds pass since last scan? */
  163.       {
  164.       ScanPortListForDeadApps(&portMgrPortList);            /* Yes, check for "dead" apps and remove them from app list */
  165.       PortListPrint(portMgrPortList);                /* Print the current list of registered applications */
  166.       lastTestTime.tv_sec = now.tv_sec;                /* Reset the last time scanned to now */
  167.       lastTestTime.tv_usec = now.tv_usec;
  168.       }
  169.     break;
  170.  
  171.       default:                                /* There was input to process */
  172.         svc_getreqset(&rpcSockets);                    /* Handle the incoming RPC requests */
  173.         break;
  174.       }                                    /* end switch */
  175.     }                                    /* end for (;;) */
  176. }                                    /* end function ListenForMessages */
  177.  
  178.  
  179.  
  180. main(int argc, char** argv)
  181. {
  182.   Sender*    sender;
  183.   Port        portMgrSender;
  184.   void        GetCommandLineOptions(int argc, char** argv);
  185.  
  186.   BuildDispatchTable(&portMgrDispatchTable);                /* Override the default RPC callbacks with my own */
  187.   (void) gethostname(portMgrHostName,sizeof(portMgrHostName));        /* Determine which host Port Manager is running on */
  188.   portMgrPortList = NULL;
  189.   portMgrSender.hostName = strdup(portMgrHostName);
  190.   portMgrSender.portNumber = 0;
  191.   sender = NewSender(&portMgrSender);                    /* Create a new Sender that doesn't try to connect with...*/
  192.                                     /* ...the PortManager, because this is the PortManager.*/
  193.   portMgrReceiver = NewReceiver(sender, "PortManager",            /* Create new Receiver to listen for messages from other apps*/
  194.                 PortMgrPortNumber);
  195.   if (portMgrReceiver == (Receiver*) NULL)
  196.   {
  197.     sprintf(diagMessage, "Port Manager could not reserve port %d to listen for messages.  Exiting.\n",
  198.         PortMgrPortNumber);
  199.     PrintDiagnostic(diagMessage);
  200.     exit(-1);
  201.   }
  202.   GetCommandLineOptions(argc, argv);
  203.   sprintf(diagMessage, "Listening on host %s on port %d.\n",
  204.       portMgrHostName,
  205.       portMgrReceiver->receivePort.portNumber);
  206.   PrintDiagnostic(diagMessage);
  207.   ListenForMessages();                            /* Begin listening for messages from other applications*/
  208.   exit(0);                                /* This function should never be called.*/
  209. }
  210.